#!/usr/local/bin/perl -w

use strict;

use Data::Dumper;
use File::Find;
use Getopt::Long;

my $_end_sub;
main();

sub main
{
	Getopt::Long::Configure(qw(pass_through bundling));
	my $start_time = 0;
	my $no_countdown;
	my $countdown;
	my $start_volume =
		`osascript -e 'get output volume of (get volume settings)'`;
	chomp $start_volume;
	my $volume = $start_volume;
	my $duration = 0;
	my $loops = 1;
	my $rate = 1;
	# afplay args: vhtrqd
	GetOptions("start|s=f" => \$start_time);
	GetOptions("volume|v=i" => \$volume);
	GetOptions("CountdownOff|C" => \$no_countdown);
	GetOptions("countdown|c" => \$countdown);
	GetOptions("duration|d=i" => \$duration);
	GetOptions("loops|l=i" => \$loops);
	GetOptions("rate|r=f" => \$rate);

	my $tmpfile;
	$_end_sub = sub
	{
		if ($start_volume != $volume)
		{
			esystem("osascript -e 'set volume output volume $start_volume'");
		}
		esystem("rm $tmpfile") if $tmpfile;
		exit;
	};
	$SIG{'INT'} = $_end_sub;

	my $search_str = pop @ARGV || die "usage error";
	$search_str =~ s/\+/\.\*/g;
	my @matched_files;

	my $wanted = sub
	{
		push(@matched_files, $File::Find::name)
			if ($File::Find::name =~ /$search_str/i);
	};

	find($wanted, "$ENV{HOME}/Music/iTunes");
	if (@matched_files == 1)
	{
		if ($start_volume != $volume)
		{
			esystem("osascript -e 'set volume output volume $volume'");
		}

		my $countdown_default = $ENV{HOME} !~ /ew/;
		$countdown = $countdown // $countdown_default;
		$countdown = undef if defined $no_countdown;
		if ($countdown)
		{
			my $countdown = 3;
			while ($countdown)
			{
				print $countdown-- . "\n";
				sleep 1;
			}
		}

		my $file = $matched_files[0];
		if ($start_time)
		{
			my $d = qx"afinfo '$file'";
			$d =~ /estimated duration: ([\d\.]+) sec/ || die;
			my $cutoff = $1;
			$d =~ /audio data file offset: (\d+)/ || die;
			my $offset = $1;

			open(my $fh, "<$file") || die;
			undef $/;
			my $text = <$fh>;
			close($fh);
			my $cut_pct = $start_time / $cutoff;
			my $cut_len =  int((length($text) - $offset) * $cut_pct);
			substr($text, $offset, $cut_len) = "";
			$tmpfile = "/tmp/jjplay.tmp.mp3";
			open(my $ofh, ">$tmpfile") || die;
			print $ofh $text;
			close($ofh);
			$file = $tmpfile;
		}

		while ($loops)
		{
			print "$loops left\n";
			--$loops;

			my $pid = fork();
			if ($pid)
			{
				eval
				{
					local $SIG{'ALRM'} = sub { die "Duration of $duration over" };
					alarm $duration / $rate;
					waitpid($pid, 0);
					alarm 0;
				};
				if ($@)
				{
					print $@;
					kill(15, $pid);
				}
			}
			else
			{
				push(@ARGV, ("-r", $rate));
				exec("afplay", @ARGV, $file);
			}
		}
	}
	else
	{
		if (@matched_files > 10)
		{
			print "ERROR: " . @matched_files . " matched files, truncating\n";
			@matched_files = @matched_files[0..9];
		}
		print Dumper \@matched_files;
	}
}


sub esystem
{
	my (@cmd) = @_;
	print "@cmd\n";
	system(@cmd);
}

END {
	$_end_sub->();
}
